#include "SysDefine.hpp"
#include "MqttClient.hpp"
extern "C" { // 用cc编译的需要加extern C包含
    #include "luckfox_gpio.h"
}

// 信号处理
void SigintHandler(int signum)
{
	switch (signum) {
    case SIGINT: // ctrl c
		case SIGQUIT: // ctrl '\'
		case SIGTSTP: // ctrl z
			SETTINGS->Debug();
			break;
	}
}

// 读取config目录
void ReadConfigDir(bool isSafeMode)
{
	DIR* dir;
	struct dirent* dirEntry;
	dir = opendir("/userdata/config");
	if (dir == NULL) {
		cout << "Cannot found config dir." << endl;
		return;
	}
	while ((dirEntry = readdir(dir)) != NULL) { // 遍历目录
		string fileName(dirEntry->d_name);
		if (fileName == "." || fileName == "..") continue; // 去掉自己
		vector<string> fnVec = StrSplit(fileName, ':');
		if (fnVec.size() == 2) {
			SETTINGS->Set(fnVec[0], fnVec[1]); // 存储到系统设置里面
		}
	}
	closedir(dir);
}

// 调整设置项
void AdjustSettings()
{
	if (SETTINGS->NotHas("netmask")) SETTINGS->Set("netmask", "255.255.255.0");
	if (SETTINGS->Has("ip")) {
		string cmdRes;
		string cmdStr = "ifconfig eth0 " + SETTINGS->GetString("ip");
		cmdStr += " netmask " + SETTINGS->GetString("netmask");
		cmdStr += " up";
		cout << "Execute Shell: " << cmdStr << endl;
		ExecuteShell(cmdStr, cmdRes);
	}
}

// zmq消息订阅测试
void* Thread_Test(void* arg)
{
	zmq::context_t ctx;
	zmq::socket_t pubSock(ctx, zmq::socket_type::pub);
	pubSock.bind(ZMQ_LINK_URL);

	while (1) {
		// cout << "main send msg" << endl;
		// pubSock.send(zmq::str_buffer("AA"), zmq::send_flags::sndmore);
		// pubSock.send(zmq::str_buffer("Message in A envelope"));
		// pubSock.send(zmq::str_buffer("BB"), zmq::send_flags::sndmore);
		// pubSock.send(zmq::str_buffer("Message in B envelope"));
		// pubSock.send(zmq::str_buffer("CC"), zmq::send_flags::sndmore);
		// pubSock.send(zmq::str_buffer("Message in C envelope"));
		ThreadSleepMs(10000);
	}
}

// 线程声明
void* Thread_UartHandler(void* arg);

void TV_Start();
void MD_UpdateFile(const char *path);

const char *g_target = "/tmp/1.jpg";

// 命令行参数解析
void InputArgParse(int argc, char* argv[])
{
  int c;
	while ((c = getopt(argc, argv, "?::f:n")) != -1) {
		switch (c) {
      case 'n':
        //u32Height = atoi(optarg);
        break;
      case 'f':
        if (optarg) g_target = optarg;
        cout << "f:" << optarg << endl;
        break;
		}
	}
}

// 主函数
int main(int argc, char* argv[])
{
	cout << "\n\n\n\n----------------------- cpp ver. [" << __cplusplus << "] -----------------------" << endl;
  InputArgParse(argc, argv);

  auto StartMs = GetSystemMs();
  //ThreadSleepMs(10*1000);
  cout << "[Main] Start running, now is " << (GetSystemMs() - StartMs) << endl;

#if 0
	json js;
	js["name"] = "pi";
  js["pi"] = 3.141;
	cout << "[ConnectMqttSrv] json test: " << js.dump() << endl;
#endif

  MD_UpdateFile(g_target);
  cout << "end" << endl;


  return 0;

	signal(SIGINT, SigintHandler); // 自定义ctrl c信号处理
	signal(SIGTSTP, SigintHandler); // 自定义ctrl z信号处理
  signal(SIGQUIT, SigintHandler); // 自定义ctrl \信号处理

	luckfox_gpio_export_direction(GPIO(GPIO2,PA2), GPIO_DIRECTION_OUTPUT);
	luckfox_gpio_export_direction(GPIO(GPIO2,PA3), GPIO_DIRECTION_INPUT);
	luckfox_gpio_set_value(GPIO(GPIO2,PA2), 0);
	bool isSafeMode = luckfox_gpio_get_value(GPIO(GPIO2,PA3)); // PA3按下则使用安全模式
	ReadConfigDir(isSafeMode); // 读取配置
	SETTINGS->Debug();
	AdjustSettings();

	// 定义zmq消息对象给mq线程用
	zmq::context_t ctx;
	zmq::socket_t pubSock(ctx, zmq::socket_type::pub);
	pubSock.bind(ZMQ_US_MSG_URL);

	// 启动mq连接
	MqttClient::GetIns()->ConnectMqttSrv(&pubSock);

	// 启动串口处理线程
	pthread_t pid_uart;
	pthread_create(&pid_uart, NULL, &Thread_UartHandler, NULL);

	// zmq消息队列示例
	zmq::context_t ctx2;
  zmq::socket_t subSock(ctx2, zmq::socket_type::sub);
  subSock.connect(ZMQ_LINK_URL);
	subSock.set(zmq::sockopt::subscribe, "AA"); // 订阅主题
  subSock.set(zmq::sockopt::subscribe, "BB");

	// 启动zmq消息发布线程
	pthread_t pid_test;
	pthread_create(&pid_test, NULL, &Thread_Test, NULL);

	// 等待zmq消息
  while (1) {
    cout << "[Main] Waitting zmq msg..." << endl;
    vector<zmq::message_t> recv_msgs;
    zmq::recv_result_t res = zmq::recv_multipart(subSock, back_inserter(recv_msgs));
    assert(res.has_value() && res.value() == 2 && "zmq recv failed"); // 条件 && 提示语
    cout << "ZMQ: [" << recv_msgs[0].to_string() << "] " << recv_msgs[1].to_string() << endl;
  }

	cout << "user app stop" << endl;
	return 0;
}